package com.pearadmin.pro.modules.applet.config;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * @author bysujc
 * @version 1.0.0
 * @ClassName WxjskUtil.java
 * @Description
 * @createTime 2021年09月19日 11:42:00
 */

public class WxjskUtil {


    @Value("${weixin.weixinMpMiniAppid}")
    private String weixinMpMiniAppid;

    @Value("${weixin.weixinMpMiniAppsecret}")
    private String weixinMpMiniAppsecret;


    private static HashMap<String, WxToken> wxTokenMap=new HashMap<String,WxToken>();

    private static Logger logger = LoggerFactory.getLogger(WxjskUtil.class); // 记录日志

    private  final static String ACCESSTOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";//从微信获得token
    private static String ER_CODE_URL = "https://api.weixin.qq.com/wxa/getwxacode";//从微信获得二维码
    // 网页授权接口
    public final static String GetPageAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";


    public final static String GetPageAccessTokenUrljsapi = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";


    //发送小程序模板
    public final static String  subscribeMessage="https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN";






    /**微信解密手机号*/
    public static String decrypt(String sessionKey,String ivData, String encrypData)  {

        try {
            byte[] encData = Base64.decodeBase64(encrypData);
            byte[] iv = Base64.decodeBase64(ivData);
            byte[] key = Base64.decodeBase64(sessionKey);
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            //解析解密后的字符串
            String str=new String(cipher.doFinal(encData), "UTF-8");
            return str;
        }catch(Exception e){
            //不抛错
        }
        return null;

    }

    public static String getBaseAccessToken(String appid, String appsecret) {
        String requestUrl = GetPageAccessTokenUrl.replace("APPID", appid).replace("SECRET", appsecret);
        HttpClient client = null;
        Date now= new Date();
        String accessToken = null;

        try {
            client = new DefaultHttpClient();
            HttpGet httpget = new HttpGet(requestUrl);
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            String response = client.execute(httpget, responseHandler);
            JSONObject OpenidJSONO = JSONObject.parseObject(response);
            logger.info(OpenidJSONO.toString());
            accessToken = String.valueOf(OpenidJSONO.get("access_token"));

            String expiresInStr = String.valueOf(OpenidJSONO.get("expires_in")); //超时时间
            //时间增加2小时
            Date lateTime = DateUtils.addSecond(now, Integer.valueOf(expiresInStr));
            Long misTime = lateTime.getTime();//失效时间
            WxToken  wxToken   =new WxToken(appid,misTime,accessToken);
            wxTokenMap.put(appid,wxToken);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.getConnectionManager().shutdown();
        }
        return accessToken;
    }


    /**
     *获取全局AccessToken
     *
     */
    public static Map<String, String> getAccessToken(String appid, String appsecret) {

        //先从缓存获取
        logger.info("appid={},appsecret={}",appid,appsecret);
        Map<String, String> result = new HashMap<String, String>();
        WxToken wxToken  =wxTokenMap.get(appid);
        Date now= new Date();
        if(null ==wxToken.getTm()) {
            String  accessToken=getBaseAccessToken(appid,appsecret);
            result.put("accessToken",accessToken);
            return result;
        }else if(now.getTime()>=wxToken.getTm()) {
            //token过期时
            String  accessToken=getBaseAccessToken(appid,appsecret);
            result.put("accessToken",accessToken);
            return result;
        }else {
            String accessToken=wxToken.getToken();
            result.put("accessToken",accessToken);
        }

        return result;
    }





    /**
     * 微信分享签名
     *
     */
    public static Map<String, String> JsapiTicket(String accessToken,String appid,String appSecret) {
        String requestUrl = GetPageAccessTokenUrljsapi.replace("ACCESS_TOKEN", accessToken);
        HttpClient client = null;
        Map<String, String> result = new HashMap<String, String>();
        try {
            client = new DefaultHttpClient();
            HttpGet httpget = new HttpGet(requestUrl);
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            String response = client.execute(httpget, responseHandler);
            logger.info(response);
            JSONObject OpenidJSONO = JSONObject.parseObject(response);
            //logger.info(OpenidJSONO.toString());
            String errcode = String.valueOf(OpenidJSONO.get("errcode"));

            if(! "0".equals(errcode)) {
                logger.info("token失效,重新开始请求token");
                Map<String, String> tokenMap=getAccessToken(appid,appSecret);
                String accessTokena=tokenMap.get("accessToken");
                String requestUrla = GetPageAccessTokenUrljsapi.replace("ACCESS_TOKEN", accessTokena);
                HttpGet httpgeta = new HttpGet(requestUrla);
                ResponseHandler<String> responseHandlera = new BasicResponseHandler();
                String responsea = client.execute(httpgeta, responseHandlera);
                logger.info("response2"+responsea);
                JSONObject OpenidJSONOa = JSONObject.parseObject(responsea);

                String errmsg = String.valueOf(OpenidJSONOa.get("errmsg"));
                String ticket = String.valueOf(OpenidJSONOa.get("ticket"));
                String expires_in = String.valueOf(OpenidJSONOa.get("expires_in"));
                result.put("errcode", errcode);
                result.put("errmsg", errmsg);
                result.put("ticket", ticket);
                result.put("expires_in", expires_in);

            }else {
                String errmsg = String.valueOf(OpenidJSONO.get("errmsg"));
                String ticket = String.valueOf(OpenidJSONO.get("ticket"));
                String expires_in = String.valueOf(OpenidJSONO.get("expires_in"));
                result.put("errcode", errcode);
                result.put("errmsg", errmsg);
                result.put("ticket", ticket);
                result.put("expires_in", expires_in);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.getConnectionManager().shutdown();
        }
        return result;
    }


    /**
     * 微信小程序发送模板
     *
     */
    public static Map<String, String> sendSubscribeMessage(String accessToken,String appid,String appSecret,String openId,String templateId,JSONObject data,String page) {

        if(StringUtils.isEmpty(accessToken)){
            Map<String, String> tokenMap=getAccessToken(appid,appSecret);
            accessToken=tokenMap.get("accessToken");
        }

        String requestUrl = subscribeMessage.replace("ACCESS_TOKEN", accessToken);

        Map<String, String> result = new HashMap<String, String>();

        JSONObject json = new JSONObject();
        json.put("touser", openId);
        json.put("template_id", templateId);
        json.put("data", data);
        if(StringUtils.isNotEmpty(page)){
            json.put("page", page); //点击模板卡片后的跳转页面，仅限本小程序内的页面。支持带参数,（示例index?foo=bar）。该字段不填则模板无跳转。
        }

        json.put("miniprogram_state", "formal"); // 跳转小程序类型：developer为开发版；trial为体验版；formal为正式版；默认为正式版
        json.put("lang", "zh_CN");

        logger.info("json={}",json.toString());
        try {
            String response  = HttpUtil.post(requestUrl,json.toString());
            JSONObject resultJSONO = JSONObject.parseObject(response);
            String errcode = String.valueOf(resultJSONO.get("errcode"));
            logger.info("-1-"+resultJSONO);
            if(! "0".equals(errcode)) {
                logger.info("token失效,重新开始请求token");
                Map<String, String> tokenMap=getAccessToken(appid,appSecret);
                String accessTokena=tokenMap.get("accessToken");

                String requestUrla = subscribeMessage.replace("ACCESS_TOKEN", accessTokena);

                String responsea  =HttpUtil.post(requestUrla,json.toString());
                JSONObject resultJSONOa = JSONObject.parseObject(responsea);
                logger.info("-2-"+resultJSONOa);

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

}
